package coll

import (
	"errors"
	"gitee.com/hongzhaomin/hzm-common-go/strutil"
	"reflect"
)

func ContainsIgnoreCase(slice []string, ele string) bool {
	ok, _ := ContainsIgnoreCaseReturnEle(slice, ele)
	return ok
}

func ContainsIgnoreCaseReturnEle(slice []string, ele string) (bool, string) {
	for _, s := range slice {
		if strutil.EqualsIgnoreCase(s, ele) {
			return true, s
		}
	}
	return false, strutil.Empty
}

func Contains[T comparable](list []T, ele T) bool {
	for _, s := range list {
		if s == ele {
			return true
		}
	}
	return false
}

func ConvertEle[T any, R any](ts []T, t2r func(t T) R) []R {
	rs := make([]R, 0, len(ts))
	for _, t := range ts {
		rs = append(rs, t2r(t))
	}
	return rs
}

// Distinct 去重
func Distinct[T comparable](list []T) []T {
	set := OfList(list).ToSet()
	return *set.ToList()
}

func RemoveAt[T comparable](src []T, index int) []T {
	if len(src) == 0 {
		return src
	}
	if index < 0 || index > len(src)-1 {
		return src
	}
	return append(src[:index], src[index+1:]...)
}

func Remove[T comparable](src []T, ele T) []T {
	index := -1
	for i, e := range src {
		if ele == e {
			index = i
			break
		}
	}
	return RemoveAt(src, index)
}

func AddAt[T comparable](src []T, index int, ele T) []T {
	if index < 0 || index > len(src) {
		return src
	}
	if index == len(src) {
		return append(src, ele)
	}
	src = append(src, ele)
	copy(src[index+1:], src[index:])
	src[index] = ele
	return src
}

// Page 根据subSize分页
func Page[T comparable](list []T, subSize int) [][]T {
	if subSize <= 0 {
		panic(errors.New("子切片大小必须大于0"))
	}
	lists := make([][]T, 0)
	BatchConsume(list, subSize, func(eles []T) {
		partList := make([]T, 0, len(eles))
		partList = append(partList, eles...)
		lists = append(lists, partList)
	})
	return lists
}

// BatchConsume 分批处理，每batchSize一批
func BatchConsume[T comparable](list []T, batchSize int, consumer func([]T)) {
	if batchSize <= 0 {
		return
	}
	var (
		size                    = len(list)
		flag                    = true
		currentPage, start, end = 1, 0, 0
	)
	for flag {
		start = (currentPage - 1) * batchSize
		end = start + batchSize
		if end >= size {
			end = size
			flag = false
		} else {
			currentPage++
		}
		// 使用原来的数组
		consumer(list[start:end])
	}
}

func isValid(a any) bool {
	// 空接口判断是否为nil，必须类型和值都为nil才会返回真
	// 大多数情况是：type不为nil, value为nil
	// 那就需要继续判断了，使用反射判断
	if a == nil {
		return false
	}
	rv := reflect.ValueOf(a)
	switch rv.Kind() {
	case reflect.Chan, reflect.Func, reflect.Map,
		reflect.Pointer, reflect.UnsafePointer,
		reflect.Interface, reflect.Slice:
		return !rv.IsNil()
	default:
		return rv.IsValid()
	}
}
